﻿using Asp.Versioning;
using FlyingEye.DeviceMaintenance;
using FlyingEye.DeviceMaintenance.Repositories;
using FlyingEye.DeviceMaintenanceServices;
using FlyingEye.Factories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace FlyingEye.Controllers
{
    [ApiVersion("1.0")]
    [Route("api/device-ops-service/v{version:apiVersion}/device-hosts")]
    [ControllerName("DeviceHost")]
    [Authorize]
    public class DeviceHostController : DefaultController
    {
        private readonly IDeviceHostRepository _deviceHostRepository;

        private readonly IDeviceMaintenanceRepository _deviceMaintenanceRepository;

        public DeviceHostController(
            IDeviceHostRepository deviceHostRepository,
            IDeviceMaintenanceRepository deviceMaintenanceRepository)
        {
            _deviceHostRepository = deviceHostRepository;
            _deviceMaintenanceRepository = deviceMaintenanceRepository;
        }

        [HttpGet("{id}/device-maintenances")]
        public async Task<ActionResult<List<DeviceMaintenanceResponse>>> GetDeviceMaintenanceAsync(Guid id)
        {
            return await this.GetInvokeAsync(async () =>
            {
                var deviceHost = await _deviceHostRepository.GetAsync(id);
                var list = await _deviceMaintenanceRepository.GetListAsync(item => item.DeviceHostId == id);

                return ObjectMapper.Map<List<DeviceMaintenanceModel>, List<DeviceMaintenanceResponse>>(list);
            });
        }

        [HttpGet]
        public async Task<ActionResult<List<DeviceHostResponse>>> GetListAsync()
        {
            return await this.GetInvokeAsync(async () =>
            {
                var list = await this._deviceHostRepository.GetListAsync();
                return ObjectMapper.Map<List<DeviceHostModel>, List<DeviceHostResponse>>(list);
            });
        }

        [HttpGet("{id}", Name = "GetByDeviceHostId")]
        public async Task<ActionResult<DeviceHostResponse>> GetAsync(Guid id)
        {
            return await this.GetInvokeAsync(async () =>
            {
                var model = await this._deviceHostRepository.GetAsync(id);
                return ObjectMapper.Map<DeviceHostModel, DeviceHostResponse>(model);
            });
        }

        [HttpPost]
        public async Task<ActionResult<DeviceHostResponse>> InsertAsync([FromBody] CreateDeviceHostRequest request)
        {
            return await this.InsertInvokeAsync(async () =>
            {
                var model = ObjectMapper.Map<CreateDeviceHostRequest, DeviceHostModel>(request);
                model = await _deviceHostRepository.InsertAsync(model);
                return ObjectMapper.Map<DeviceHostModel, DeviceHostResponse>(model);
            }, "GetByDeviceHostId", e => new { e.Id });
        }

        [HttpPut]
        public async Task<ActionResult<DeviceHostResponse>> UpdateAsync([FromBody] UpdateDeviceHostRequest request)
        {
            return await this.PutInvokeAsync(async () =>
            {
                var model = ObjectMapper.Map<UpdateDeviceHostRequest, DeviceHostModel>(request);
                model = await _deviceHostRepository.UpdateAsync(model);
                return ObjectMapper.Map<DeviceHostModel, DeviceHostResponse>(model);
            });
        }

        [HttpDelete("{id}")]
        public async Task<NoContentResult> DeleteAsync(Guid id)
        {
            return await this.DeleteInvokeAsync(async () =>
            {
                await _deviceHostRepository.DeleteAsync(id);
            });
        }
    }
}
